package com.carbon.carbonmanager.service;

import com.carbon.carbonmanager.mapper.TradeMapper;
import com.carbon.carbonmanager.model.EnterpressInfo;
import com.carbon.carbonmanager.model.TradeOrderInfo;
import com.carbon.carbonmanager.model.TradeRecodeInfo;
import com.carbon.carbonmanager.unit.Pager;
import com.carbon.carbonmanager.unit.PagerData;
import com.carbon.carbonmanager.unit.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 订单交易实现层
 * */
@Service
public class TradeService {
    @Autowired
    TradeMapper tradeMapper;

    /**
     * 发布交易（包括购买和售卖）
     * @return error = 0则执行成功
     * 判断交易方式通过 trade_type = 0 购买，trade_type = 1 售卖
     * */
    public Response publishTradeOrder(TradeOrderInfo tradeOrderInfo){
        Integer trade_type = tradeOrderInfo.getTrade_type();
        if(trade_type==0){
            //发布购买订单 trade_type = 0
            if(tradeMapper.publishTradeOrder(tradeOrderInfo)==0){
                //发布成功
                return new Response(200,"发布新交易订单成功",null);
            }else {
                //发布失败
                return new Response(203,"发布新交易订单失败",null);
            }
        }else{
            //发布售卖订单 trade_type = 1
            System.out.println(tradeOrderInfo);
            if(tradeMapper.publishTradeOrderSeller(tradeOrderInfo)==0){
                //发布成功
                return new Response(200,"发布新交易订单成功",null);
            }else {
                //发布失败
                return new Response(203,"发布售卖交易订单失败",null);
            }
        }
    }

    /*************************************************************************************
     * 管理自己的碳信用资产1
     * 根据发布人id获取自身订单列表数据，带分页
     * */
    private List<TradeOrderInfo> getTradeOrderListByPublishId(Pager pager){
        //计算起始角标
        Integer currentPage = pager.getCurrentPage();
        Integer pageSize = pager.getPageSize();
        Integer startIndex = (currentPage-1)*pageSize;
        pager.setStartIndex(startIndex);
        return tradeMapper.getTradeOrderListByPublishId(pager);
    }

    /**
     * 管理自己的碳信用资产2
     * 根据发布人id获取自身订单数据列表总条数用于计算总页码
     * */
    private Integer getTradeOrderListTotalCountsByPublishId(Pager pager){
        return tradeMapper.getTradeOrderListTotalCountsByPublishId(pager);
    }

    /**
     * 管理自己的碳信用资产3
     * 计算总页码
     * */
    private Integer getTradeOrderListTotalPagesByPublishId(Pager pager){
        //获取数据总条数计算页码
        Integer totalCounts = getTradeOrderListTotalCountsByPublishId(pager);
        Integer pageSize = pager.getPageSize();
        Integer totalPages = 0;
        //求模计算分数总页码
        if(totalCounts%pageSize>0){
            totalPages = totalCounts/pageSize +1;
        }else{
            totalPages = totalCounts/pageSize;
        }
        return totalPages;
    }

    /**
     * 管理自己的碳信用资产4
     * 装载分页数据
     * */
    public Response getTradeOrderDataByPublishId(Pager pager){
        //实例化装载对象
        PagerData pagerData = new PagerData();
        pagerData.setPageTotal(getTradeOrderListTotalPagesByPublishId(pager));
        pagerData.setData(getTradeOrderListByPublishId(pager));
        return new Response(200,"查询数据成功",pagerData);
    }

    /**
     * 确认发布订单
     * 修改订单状态前进行验证
     * */
    public Response applyTradeOrder(TradeOrderInfo tradeOrderInfo){
        TradeOrderInfo tradeInfo = tradeMapper.validateTradeOrderIsCurrentUser(tradeOrderInfo);
        if(tradeInfo.getPublish_id() == tradeOrderInfo.getPublish_id()){
            //当前修改者id与要修改的订单所有者id相同
            return new Response(200,"确认发布成功",tradeMapper.applyTradeOrder(tradeOrderInfo));
        }else {
            //
            return new Response(203,"您无权修改该订单",null);
        }
    }

    /**
     * 确认撤销订单
     * 修改订单状态前进行验证
     * 验证订单是否已经完成交易状态，完成的订单不能撤销
     * */
    public Response cancelTradeOrder(TradeOrderInfo tradeOrderInfo){
        TradeOrderInfo tradeInfo = tradeMapper.validateTradeOrderIsCurrentUser(tradeOrderInfo);
        if(tradeInfo.getPublish_id() == tradeOrderInfo.getPublish_id()){
            //当前修改者id与要修改的订单所有者id相同
            if(tradeInfo.getTrade_state()==2){
                //已经交易完成的订单不能撤销
                return new Response(203,"该订单已完成交易，无法撤销",null);
            }else{
                return new Response(200,"确认发布成功",tradeMapper.cancelTradeOrder(tradeOrderInfo));
            }
        }else {
            //
            return new Response(203,"您无权修改该订单",null);
        }
    }


    /**************************************************************************************
     * 交易市场信息列表分页数据1
     *
     * */
    private List<TradeOrderInfo> getTradeMarketDataByPager(Pager pager){
        Integer currentPage = pager.getCurrentPage();
        Integer pageSize = pager.getPageSize();
        Integer startIndex = (currentPage - 1)*pageSize;
        pager.setStartIndex(startIndex);
        return tradeMapper.getTradeMarketDataByPager(pager);
    }

    /**
     * 交易市场信息列表分页数据2
     * 获取交易市场数据总数用于计算页码
     * */
    private Integer getTradeMarketDataTotalCounts(Pager pager){
        return tradeMapper.getTradeMarketDataTotalCounts(pager);
    }

    /**
     * 交易市场信息列表分页数据3
     * 计算页码
     * */
    private Integer getTradeMarketTotalPages(Pager pager){
        Integer totalCounts = getTradeMarketDataTotalCounts(pager);
        Integer pageSize = pager.getPageSize();
        Integer totalPages = 0;
        //计算总页码
        if(totalCounts%pageSize>0){
            totalPages = totalCounts/pageSize + 1;
        }else{
            totalPages = totalCounts/pageSize;
        }
        return totalPages;
    }

    /**
     * 交易市场信息列表分页数据4
     * 装载分页数据
     * */
    public Response getTradeMarketPagerData(Pager pager){
        PagerData pagerData = new PagerData();
        pagerData.setData(getTradeMarketDataByPager(pager));
        pagerData.setPageTotal(getTradeMarketTotalPages(pager));
        return new Response(200,"加载交易市场分页数据成功",pagerData);
    }

    /**
     * 交易市场：交易买入
     * */
    public Response tradeBuyOrder(TradeOrderInfo tradeOrderInfo){
        //判断当前订单未处于发布状态返回
        EnterpressInfo enterInfo = tradeMapper.getEnterInfoByTradeUserId(tradeOrderInfo);
        if(tradeOrderInfo.getPublish_id()==tradeOrderInfo.getTradeuser_id()){
            //不能与自己交易
            return new Response(203,"不能与自己交易",null);
        }else{
            //比对交易余额
            if(tradeOrderInfo.getTrade_quantity()*tradeOrderInfo.getTrade_offer()<=enterInfo.getBalance()){
                //余额满足
                if(tradeMapper.tradeBuyOrder(setTradeLog(tradeOrderInfo))==0){
                    //交易成功
                    return new Response(200,"交易成功",null);
                }else{
                    //交易失败
                    return new Response(203,"交易失败",null);
                }
            }else{
                //余额不满足
                return new Response(203,"余额不足",null);
            }
        }
    }

    /**
     * 交易市场：交易卖出
     * */
    public Response tradeSellOrder(TradeOrderInfo tradeOrderInfo){
        if(tradeOrderInfo.getPublish_id()==tradeOrderInfo.getTradeuser_id()){
            //不能与自己交易
            return new Response(203,"不能与自己交易",null);
        }else{
            //比对交易余额
            if(tradeOrderInfo.getTrade_quantity()<=tradeMapper.getEnterInfoByTradeUserId(tradeOrderInfo).getAvailable_quantity()){
                //余额满足
                if(tradeMapper.tradeSellOrder(setTradeLog(tradeOrderInfo))==0){
                    //交易成功
                    return new Response(200,"交易成功",null);
                }else{
                    //交易失败
                    return new Response(203,"交易失败",null);
                }
            }else{
                //余额不满足
                return new Response(203,"可以碳信用不足",null);
            }
        }
    }

    /**
     * 交易成功后的日志信息记录
     * 封装方法
     * */
    private TradeOrderInfo setTradeLog(TradeOrderInfo tradeOrderInfo){
        //判断订单交易类型
        if(tradeOrderInfo.getTrade_type()==0){
            //买方
            String logString = tradeOrderInfo.getPublish_id()+"向"+tradeOrderInfo.getTradeuser_id()+"购买碳信用额度"+tradeOrderInfo.getTrade_quantity()+"(tCO2e)成功。";
            Integer logHashValue = logString.hashCode();
            tradeOrderInfo.setRecord_log(logString);
            tradeOrderInfo.setRecord_hashvalue(logHashValue);
            return tradeOrderInfo;
        }else{
            //卖方
            String logString = tradeOrderInfo.getPublish_id()+"向"+tradeOrderInfo.getTradeuser_id()+"售卖碳信用额度"+tradeOrderInfo.getTrade_quantity()+"(tCO2e)成功。";
            Integer logHashValue = logString.hashCode();
            tradeOrderInfo.setRecord_log(logString);
            tradeOrderInfo.setRecord_hashvalue(logHashValue);
            return tradeOrderInfo;
        }
    }

    /*******************************************************
     * 根据用户id获取其自身购买或者售卖的日志信息1
     * 即可以是购买者也可以是售卖者
     * */
    private List<TradeRecodeInfo> getTradeRecordMapperDataByCurrentUser(Pager pager){
        Integer currentPage = pager.getCurrentPage();
        Integer pageSize = pager.getPageSize();
        Integer startIndex = (currentPage - 1) * pageSize;
        pager.setStartIndex(startIndex);
        return tradeMapper.getTradeRecordMapperDataByCurrentUser(pager);
    }

    /**
     * 根据用户id获取其自身购买或者售卖的日志信息2
     * 获取日志总数
     * */
    private Integer getTradeRecordMapperDataCountsByCurrentUser(Pager pager){
        return tradeMapper.getTradeRecordMapperDataCountsByCurrentUser(pager);
    }

    /**
     * 根据用户id获取其自身购买或者售卖的日志信息3
     * 计算总页码
     * */
    private Integer getTradeRecordDataTotalPages(Pager pager){
        Integer totalCounts = getTradeRecordMapperDataCountsByCurrentUser(pager);
        Integer pageSize = pager.getPageSize();
        Integer totalPage = 1;
        //计算
        if(totalCounts%pageSize>0){
            totalPage = totalCounts/pageSize + 1;
        }else {
            totalPage = totalCounts/pageSize;
        }
        return totalPage;
    }

    /**
     * 根据用户id获取其自身购买或者售卖的日志信息4
     * 装载数据
     * */
    public Response getTradeRecordDataByCurrentUser(Pager pager){
        PagerData pagerData = new PagerData();
        pagerData.setData(getTradeRecordMapperDataByCurrentUser(pager));
        pagerData.setPageTotal(getTradeRecordDataTotalPages(pager));
        return new Response(200,"加载日志记录成功",pagerData);
    }
}
